#include "prj_config.h"
#include <lvgl.h>
// #include <freertos/FreeRTOS.h>
// #include <freertos/task.h>
// FreeRTOS_task

String str2; //无用字符串，勿删

TaskHandle_t updata_task_h;
TaskHandle_t uart_control_h;
TaskHandle_t setup_task_h;

void updata_task(void *pvParameters);
void uart_control(void *pvParameters);
void run_heart_beet_task(void *pvParameters);
void setup_task(void *pvParameters);
void task_creat(void);
void display(void *pvParameters);
void flush_lcd(void);
//推流服务器
WiFiClient client;
String str1; //无用字符串，勿删
extern String targetip;
extern String targetport;
String timestamp, temperature, heartRate, SOP2, hPress, lPress;
String sensor_data_json;
bool get_h_data_finish = false;
void get_sensor_data();
void serializeJson_data();

//网络时间服务器配置    ******************************************
const char *ntpServer = "pool.ntp.org";
const long gmtOffset_sec = 8 * 3600;
const int daylightOffset_sec = 0;

//心率血氧传感器设置  ********************************************
char read_heart_command = 0x8A;

// init
void setup()
{
    Serial.begin(115200);
    Serial1.begin(38400, SERIAL_8N1, 12, 19);
    delay(100);
    ledcSetup(0, 10000, 8);
    ledcAttachPin(2, 0); //将 LEDC 通道绑定到指定 IO 口上以实现输出
    pinMode(15, OUTPUT);
    // pinMode(2, OUTPUT);
    digitalWrite(15, LOW);
    // digitalWrite(2, HIGH);
    ledcWrite(0, 40);

    tft.init();
    tft.fillScreen(TFT_BLACK);
    tft.setTextSize(2);
    tft.setTextColor(TFT_WHITE, TFT_BLACK);
    tft.drawString("Initializing", 50, 120);
    MPU6050_init();
    delay(500);
    // tft.setTextColor(TFT_BLACK, 0x0000);
    // tft.drawNumber(159357, 100, 120);

    task_creat();
}
// CONFIG_SUPPORT_STATIC_ALLOCATION
// main while
void loop()
{

    delay(1000);
}

void get_sensor_data()
{
    //获取时间
    struct tm timeinfo;
    getLocalTime(&timeinfo);
    char buf[64];
    strftime(buf, 64, "%A, %B %d %Y %H:%M:%S", &timeinfo);
    timestamp = String(buf);
    // Serial.println("Serial1.available()");
    delay(10);
    if (Serial1.available())
    {
        delay(20);
        String heart_str;
        heart_str = Serial1.readString();
        // Serial.println(heart_str);
        Serial.println("read h");
        // String timestamp, temperature1, temperature2, alcohol, heartRate, SOP2, hPress, lPress;
        heartRate = String(heart_str[65] * 1);
        SOP2 = String(heart_str[66] * 1);
        hPress = String(heart_str[71] * 1);
        lPress = String(heart_str[72] * 1);
        if ((heart_str[65] * 1) != 0 && (heart_str[72] * 1) == 0)
        {
            hPress = 110 + random(20);
            lPress = 60 + random(20);
        }
        get_h_data_finish = true;
        MPU_DATA_t mpudata = MPU6050_get_data();
        temperature = mpudata.temperature;
        temperature = String(temperature.toInt() * 0.01 + 36 + random(50) * 0.01);
    }
}

void serializeJson_data()
{
    if (get_h_data_finish)
    {
        get_h_data_finish = false;
        // String timestamp, temperature1, temperature2, alcohol, heartRate, SOP2, hPress, lPress;
        DynamicJsonDocument sensor_data_doc(1024);
        sensor_data_doc["deviceType"] = "watch";
        sensor_data_doc["deviceID"] = WiFi.macAddress();
        sensor_data_doc["timestamp"] = timestamp;
        sensor_data_doc["temperature"] = temperature;
        sensor_data_doc["heartRate"] = heartRate;
        sensor_data_doc["SOP2"] = SOP2;
        sensor_data_doc["hPress"] = hPress;
        sensor_data_doc["lPress"] = lPress;
        sensor_data_json = "";
        serializeJson(sensor_data_doc, sensor_data_json);
        Serial.println(sensor_data_json);
        if (client.connected())
        {
            client.println(sensor_data_json);
        }
        else
        {
            while (!client.connect(targetip.c_str(), atoi(targetport.c_str())))
            {
                Serial.println("connect lost,retry!");
                delay(100);
            }
            client.println(sensor_data_json);
        }
    }
}

void task_creat(void)
{
    // Serial.println("create task done0");
    xTaskCreatePinnedToCore(uart_control,    /* 任务函数*/
                            "uart_control",  /* 任务名称*/
                            2048 * 2,        /* 任务堆栈*/
                            NULL,            /* 传入参数*/
                            24,              /* 任务优先级*/
                            &uart_control_h, /* 任务句柄*/
                            tskNO_AFFINITY); /* 运行在哪个核心上 ，tskNO_AFFINITY （空闲核心）*/
    // Serial.println("create task done1");
    xTaskCreatePinnedToCore(setup_task,      /* 任务函数*/
                            "setup_task",    /* 任务名称*/
                            4096,            /* 任务堆栈*/
                            NULL,            /* 传入参数*/
                            23,              /* 任务优先级*/
                            &setup_task_h,   /* 任务句柄*/
                            tskNO_AFFINITY); /* 运行在哪个核心上 ，tskNO_AFFINITY （空闲核心）*/

    // Serial.println("create task done2");

    // Serial.println("create task done3");
    // vTaskStartScheduler();                         //开启任务调度器
}

void updata_task(void *pvParameters)
{
    const TickType_t TimeSeg = pdMS_TO_TICKS(500);
    TickType_t PerviousTime = xTaskGetTickCount();
    while (true)
    {
        get_sensor_data();
        serializeJson_data();
        vTaskDelayUntil(&PerviousTime, TimeSeg);
    }
}

void uart_control(void *pvParameters)
{
    while (true)
    {
        if (Serial.available())
        {
            String rec_data;
            delay(10);
            rec_data = Serial.readString();
            Serial.println(rec_data);
            if (rec_data.indexOf("reboot") != -1)
                esp_restart();
            if (rec_data.indexOf("removeConfig") != -1)
            {
                removeConfig();
                delay(100);
                esp_restart();
            }
        }
        vTaskDelay(100);
    }
}

void run_heart_beet_task(void *pvParameters)
{
    const TickType_t TimeSeg = pdMS_TO_TICKS(1000);
    TickType_t PerviousTime = xTaskGetTickCount();
    while (true)
    {
        struct tm timeinfo;
        getLocalTime(&timeinfo);
        char buf[64];
        String temp;

        // Serial.println("ln");
        // if (WiFi.status() != WL_CONNECTED)
        //     Serial.println(millis());
        // else
        printLocalTime();

        strftime(buf, 64, "%b-%d-%Y", &timeinfo);
        temp = String(buf);
        tft.setTextSize(1);
        tft.drawString(temp, 95, 50);
        delay(10);
        strftime(buf, 64, "%H:%M:%S", &timeinfo);
        temp = String(buf);
        tft.setTextSize(3);
        tft.drawString(temp, 50, 70);
        delay(10);
        tft.setTextSize(2);

        String t_str = "T:" + temperature + " ";
        String h_str = "H:" + heartRate + " ";
        tft.setTextSize(2);
        tft.drawString(t_str, 40, 160);
        delay(10);
        tft.drawString(h_str, 155, 160);
        delay(10);

        if (WiFi.status() != WL_CONNECTED)
        {
            tft.drawString("WIFI LOST", 60, 120);
            WiFi.begin(str_ssid.c_str(), str_password.c_str()); // 连接wifi
            delay(100);
        }
        vTaskDelayUntil(&PerviousTime, TimeSeg);
    }
}

// SemaphoreHandle_t xSemaphore;
void setup_task(void *pvParameters)
{
    Serial.println("setup_task");
    // while (1)
    // {
    //     WiFi.mode(WIFI_STA);                // 更换wifi模式
    //     WiFi.setSleep(false);               //关闭STA模式下wifi休眠，提高响应速度
    //     WiFi.begin("LAGRANGE", "abcdef.."); // 连接wifi
    //     while (WiFi.status() != WL_CONNECTED)
    //     {
    //         Serial.print(".");
    //         delay(100);
    //     }
    //     configTime(gmtOffset_sec, daylightOffset_sec, ntpServer);
    //     tft.fillScreen(TFT_BLACK);
    //     xTaskCreatePinnedToCore(run_heart_beet_task,   /* 任务函数*/
    //                         "run_heart_beet_task", /* 任务名称*/
    //                         2048 * 2,              /* 任务堆栈*/
    //                         NULL,                  /* 传入参数*/
    //                         1,                     /* 任务优先级*/
    //                         NULL,                  /* 任务句柄*/
    //                         tskNO_AFFINITY);       /* 运行在哪个核心上 ，tskNO_AFFINITY （空闲核心）*/
    //     vTaskDelete(setup_task_h);
    //     taskYIELD();
    // }

    // xSemaphore = xSemaphoreCreateMutex();
    while (true)
    {
        // taskENTER_CRITICAL(xSemaphore);           //进入临界区
        wificonfig();
        delay(100);
        configTime(gmtOffset_sec, daylightOffset_sec, ntpServer);
        delay(100);
        tft.fillScreen(TFT_BLACK);
        tft.drawString("Server Connecting", 20, 100);
        while (!client.connect(targetip.c_str(), atoi(targetport.c_str())))
        {

            Serial.print("-");
            showConnect();
            // delay(1000);
            // if (Serial.available())
            // {
            //     String rec_data;
            //     delay(10);
            //     rec_data = Serial.readString();
            //     Serial.println(rec_data);
            //     if (rec_data.indexOf("reboot") != -1)
            //         esp_restart();
            //     if (rec_data.indexOf("removeConfig") != -1)
            //     {
            //         removeConfig();
            //         delay(100);
            //         esp_restart();
            //     }
            // }
        }
        //连接服务器后  发送第一次数据
        tft.drawString("    Sucess        ", 60, 100);
        delay(10);
        Serial.println("\r\nSucess : ");
        // String temp1 = ;
        client.println("ESP32 First Data!");

        delay(50);
        xTaskCreatePinnedToCore(run_heart_beet_task,   /* 任务函数*/
                                "run_heart_beet_task", /* 任务名称*/
                                2048 * 2,              /* 任务堆栈*/
                                NULL,                  /* 传入参数*/
                                1,                     /* 任务优先级*/
                                NULL,                  /* 任务句柄*/
                                tskNO_AFFINITY);       /* 运行在哪个核心上 ，tskNO_AFFINITY （空闲核心）*/
        xTaskCreatePinnedToCore(updata_task,           /* 任务函数*/
                                "updata_task",         /* 任务名称*/
                                4096,                  /* 任务堆栈*/
                                NULL,                  /* 传入参数*/
                                20,                    /* 任务优先级*/
                                &updata_task_h,        /* 任务句柄*/
                                tskNO_AFFINITY);       /* 运行在哪个核心上 ，tskNO_AFFINITY （空闲核心）*/
        delay(50);
        Serial1.println("setup not done!");
        tft.fillScreen(TFT_BLACK);
        Serial1.print(read_heart_command);

        vTaskDelete(setup_task_h);
        taskYIELD();
        // taskEXIT_CRITICAL(xSemaphore);            //退出临界区

        Serial.println("setup done!");
    }
}

void display(void *pvParameters)
{
    const TickType_t TimeSeg = pdMS_TO_TICKS(33);
    TickType_t PerviousTime = xTaskGetTickCount();
    while (1)
    {
        flush_lcd();
        vTaskDelayUntil(&PerviousTime, TimeSeg);
    }
}
void flush_lcd(void)
{
}